package collector

import (
	"bufio"
	"context"
	"fmt"
	"net"
	"regexp"
	"strconv"
	"strings"
	"time"

	"go-agent/pkg/logger"
)

// ZookeeperMetrics Zookeeper指标数据结构
type ZookeeperMetrics struct {
	// 响应相关
	ResponseTime         float64   `json:"response_time"`         // 毫秒
	ResponseSizeLast     int64     `json:"response_size_last"`    // 最后响应大小(字节)
	ResponseSizeMax      int64     `json:"response_size_max"`     // 最大响应大小(字节)
	ResponseSizeMin      int64     `json:"response_size_min"`     // 最小响应大小(字节)
	ResponseSizeAvg      float64   `json:"response_size_avg"`     // 平均响应大小(字节)

	// 连接相关
	ClientConnected      int64     `json:"client_connected"`      // 连接的客户端数
	ClientConnections    int64     `json:"client_connections"`    // 总连接数
	MaxClientConnections int64     `json:"max_client_connections"` // 最大连接数

	// 性能相关
	CacheEnabled         int       `json:"cache_enabled"`         // 缓存是否启用 (0/1)
	AvgLatency           float64   `json:"avg_latency"`           // 平均延迟(ms)
	MaxLatency           float64   `json:"max_latency"`           // 最大延迟(ms)
	MinLatency           float64   `json:"min_latency"`           // 最小延迟(ms)

	// 数据相关
	ZnodeCount           int64     `json:"znode_count"`           // ZNode数量
	DataSize             int64     `json:"data_size"`             // 数据大小
	EphemeralCount       int64     `json:"ephemeral_count"`       // 临时节点数

	// 服务器状态
	ServerState          string    `json:"server_state"`          // 服务器状态
	Version              string    `json:"version"`               // 版本信息
	ServerId             int64     `json:"server_id"`             // 服务器ID

	// 统计信息
	PacketsSent          int64     `json:"packets_sent"`          // 发送包数
	PacketsReceived      int64     `json:"packets_received"`      // 接收包数
	OutstandingRequests  int64     `json:"outstanding_requests"`  // 未处理请求数

	// 采集时间戳
	Timestamp            time.Time `json:"timestamp"`
}

// ZookeeperConfig Zookeeper采集器配置
type ZookeeperConfig struct {
	Enabled         bool   `mapstructure:"enabled"`
	Host            string `mapstructure:"host"`              // Zookeeper主机
	Port            int    `mapstructure:"port"`              // 端口
	Timeout         int    `mapstructure:"timeout"`           // 连接超时时间（秒）
	Commands        []string `mapstructure:"commands"`        // 要执行的4字命令列表

	// 历史数据跟踪
	TrackHistory    bool   `mapstructure:"track_history"`     // 是否跟踪历史数据
	MaxHistorySize  int    `mapstructure:"max_history_size"`  // 最大历史记录数
}

// ZookeeperCollector Zookeeper采集器
type ZookeeperCollector struct {
	config         ZookeeperConfig

	// 历史数据存储
	responseSizeHistory []int64
	latencyHistory      []float64

	// 最大值跟踪
	maxResponseSize    int64
	maxLatency         float64
	minLatency         float64

	// 正则表达式缓存
	statRegexes        map[string]*regexp.Regexp
}

// NewZookeeperCollector 创建Zookeeper采集器
func NewZookeeperCollector(config ZookeeperConfig) *ZookeeperCollector {
	// 设置默认值
	if config.Host == "" {
		config.Host = "127.0.0.1"
	}
	if config.Port == 0 {
		config.Port = 2181
	}
	if config.Timeout == 0 {
		config.Timeout = 10
	}
	if len(config.Commands) == 0 {
		config.Commands = []string{"stat", "conf", "envi"}
	}
	if config.MaxHistorySize == 0 {
		config.MaxHistorySize = 100
	}

	// 编译常用的正则表达式
	statRegexes := map[string]*regexp.Regexp{
		"connections":    regexp.MustCompile(`Connections:\s*(\d+)`),
		"latency":        regexp.MustCompile(`Latency min/avg/max:\s*(\d+)/(\d+)/(\d+)`),
		"received":       regexp.MustCompile(`Received:\s*(\d+)`),
		"sent":          regexp.MustCompile(`Sent:\s*(\d+)`),
		"outstanding":    regexp.MustCompile(`Outstanding:\s*(\d+)`),
		"znode_count":    regexp.MustCompile(`Zxid:\s*0x[a-fA-F0-9]+\s*\nMode:\s*\w+\s*\nNode count:\s*(\d+)`),
		"node_count":     regexp.MustCompile(`Node count:\s*(\d+)`),
		"version":        regexp.MustCompile(`Zookeeper version:\s*([^\n,]+)`),
		"server_state":   regexp.MustCompile(`Mode:\s*(\w+)`),
	}

	collector := &ZookeeperCollector{
		config:             config,
		responseSizeHistory: make([]int64, 0, config.MaxHistorySize),
		latencyHistory:     make([]float64, 0, config.MaxHistorySize),
		statRegexes:        statRegexes,
		minLatency:         999999, // 初始化为很大的值
	}

	return collector
}

// Collect 采集Zookeeper指标
func (c *ZookeeperCollector) Collect(ctx context.Context) (*ZookeeperMetrics, error) {
	if !c.config.Enabled {
		return nil, fmt.Errorf("Zookeeper采集器未启用")
	}

	metrics := &ZookeeperMetrics{
		Timestamp: time.Now(),
	}

	// 执行各种4字命令获取不同的指标
	for _, command := range c.config.Commands {
		start := time.Now()
		response, err := c.executeCommand(ctx, command)
		responseTime := float64(time.Since(start).Nanoseconds()) / 1e6 // 毫秒

		if err != nil {
			logger.Warnf("执行Zookeeper命令 '%s' 失败: %v", command, err)
			continue
		}

		// 更新响应时间
		if metrics.ResponseTime == 0 || responseTime > metrics.ResponseTime {
			metrics.ResponseTime = responseTime
		}

		// 更新响应大小
		responseSize := int64(len(response))
		metrics.ResponseSizeLast = responseSize

		// 解析不同命令的响应
		switch command {
		case "stat":
			c.parseStatResponse(response, metrics)
		case "conf":
			c.parseConfResponse(response, metrics)
		case "envi":
			c.parseEnviResponse(response, metrics)
		case "srvr":
			c.parseServerResponse(response, metrics)
		}

		// 更新历史数据
		c.updateHistory(responseSize, responseTime)
	}

	// 计算统计数据
	c.calculateStatistics(metrics)

	logger.Debugf("Zookeeper指标采集完成: 连接数=%d, 响应时间=%.2fms, ZNode数=%d",
		metrics.ClientConnected, metrics.ResponseTime, metrics.ZnodeCount)

	return metrics, nil
}

// executeCommand 执行Zookeeper 4字命令
func (c *ZookeeperCollector) executeCommand(ctx context.Context, command string) (string, error) {
	address := fmt.Sprintf("%s:%d", c.config.Host, c.config.Port)

	dialer := &net.Dialer{
		Timeout: time.Duration(c.config.Timeout) * time.Second,
	}

	conn, err := dialer.DialContext(ctx, "tcp", address)
	if err != nil {
		return "", fmt.Errorf("连接Zookeeper失败 %s: %v", address, err)
	}
	defer conn.Close()

	// 设置读写超时
	deadline := time.Now().Add(time.Duration(c.config.Timeout) * time.Second)
	conn.SetDeadline(deadline)

	// 发送命令
	_, err = conn.Write([]byte(command))
	if err != nil {
		return "", fmt.Errorf("发送命令失败: %v", err)
	}

	// 读取响应
	var response strings.Builder
	scanner := bufio.NewScanner(conn)
	for scanner.Scan() {
		response.WriteString(scanner.Text())
		response.WriteString("\n")
	}

	if err := scanner.Err(); err != nil {
		return "", fmt.Errorf("读取响应失败: %v", err)
	}

	return response.String(), nil
}

// parseStatResponse 解析stat命令响应
func (c *ZookeeperCollector) parseStatResponse(response string, metrics *ZookeeperMetrics) {
	// 解析连接数
	if match := c.statRegexes["connections"].FindStringSubmatch(response); len(match) > 1 {
		if val, err := strconv.ParseInt(match[1], 10, 64); err == nil {
			metrics.ClientConnected = val
			metrics.ClientConnections = val
		}
	}

	// 解析延迟信息
	if match := c.statRegexes["latency"].FindStringSubmatch(response); len(match) > 3 {
		if min, err := strconv.ParseFloat(match[1], 64); err == nil {
			metrics.MinLatency = min
		}
		if avg, err := strconv.ParseFloat(match[2], 64); err == nil {
			metrics.AvgLatency = avg
		}
		if max, err := strconv.ParseFloat(match[3], 64); err == nil {
			metrics.MaxLatency = max
		}
	}

	// 解析接收和发送的包数
	if match := c.statRegexes["received"].FindStringSubmatch(response); len(match) > 1 {
		if val, err := strconv.ParseInt(match[1], 10, 64); err == nil {
			metrics.PacketsReceived = val
		}
	}

	if match := c.statRegexes["sent"].FindStringSubmatch(response); len(match) > 1 {
		if val, err := strconv.ParseInt(match[1], 10, 64); err == nil {
			metrics.PacketsSent = val
		}
	}

	// 解析未处理请求数
	if match := c.statRegexes["outstanding"].FindStringSubmatch(response); len(match) > 1 {
		if val, err := strconv.ParseInt(match[1], 10, 64); err == nil {
			metrics.OutstandingRequests = val
		}
	}

	// 解析节点数量
	if match := c.statRegexes["node_count"].FindStringSubmatch(response); len(match) > 1 {
		if val, err := strconv.ParseInt(match[1], 10, 64); err == nil {
			metrics.ZnodeCount = val
		}
	}

	// 解析服务器状态
	if match := c.statRegexes["server_state"].FindStringSubmatch(response); len(match) > 1 {
		metrics.ServerState = strings.TrimSpace(match[1])
	}

	// 解析版本信息
	if match := c.statRegexes["version"].FindStringSubmatch(response); len(match) > 1 {
		metrics.Version = strings.TrimSpace(match[1])
	}
}

// parseConfResponse 解析conf命令响应
func (c *ZookeeperCollector) parseConfResponse(response string, metrics *ZookeeperMetrics) {
	// 解析配置相关信息
	scanner := bufio.NewScanner(strings.NewReader(response))
	for scanner.Scan() {
		line := strings.TrimSpace(scanner.Text())
		if strings.Contains(line, "maxClientCnxns") {
			parts := strings.Split(line, "=")
			if len(parts) == 2 {
				if val, err := strconv.ParseInt(strings.TrimSpace(parts[1]), 10, 64); err == nil {
					metrics.MaxClientConnections = val
				}
			}
		}
		// 可以解析其他配置项
	}
}

// parseEnviResponse 解析envi命令响应
func (c *ZookeeperCollector) parseEnviResponse(response string, metrics *ZookeeperMetrics) {
	// 解析环境变量和JVM信息，可以用于判断缓存等功能是否启用
	if strings.Contains(response, "cache") || strings.Contains(response, "Cache") {
		metrics.CacheEnabled = 1
	}
}

// parseServerResponse 解析srvr命令响应
func (c *ZookeeperCollector) parseServerResponse(response string, metrics *ZookeeperMetrics) {
	// srvr命令提供服务器统计信息，类似stat但更简洁
	c.parseStatResponse(response, metrics) // 复用stat解析逻辑
}

// updateHistory 更新历史数据
func (c *ZookeeperCollector) updateHistory(responseSize int64, responseTime float64) {
	if !c.config.TrackHistory {
		return
	}

	// 更新响应大小历史
	c.responseSizeHistory = append(c.responseSizeHistory, responseSize)
	if len(c.responseSizeHistory) > c.config.MaxHistorySize {
		c.responseSizeHistory = c.responseSizeHistory[1:]
	}

	// 更新延迟历史
	c.latencyHistory = append(c.latencyHistory, responseTime)
	if len(c.latencyHistory) > c.config.MaxHistorySize {
		c.latencyHistory = c.latencyHistory[1:]
	}

	// 更新最大值
	if responseSize > c.maxResponseSize {
		c.maxResponseSize = responseSize
	}

	// 更新延迟范围
	if responseTime > c.maxLatency {
		c.maxLatency = responseTime
	}
	if responseTime < c.minLatency {
		c.minLatency = responseTime
	}
}

// calculateStatistics 计算统计数据
func (c *ZookeeperCollector) calculateStatistics(metrics *ZookeeperMetrics) {
	// 设置历史最大响应大小
	metrics.ResponseSizeMax = c.maxResponseSize

	// 计算平均响应大小
	if len(c.responseSizeHistory) > 0 {
		var sum int64
		var min int64 = 999999999
		for _, size := range c.responseSizeHistory {
			sum += size
			if size < min {
				min = size
			}
		}
		metrics.ResponseSizeAvg = float64(sum) / float64(len(c.responseSizeHistory))
		metrics.ResponseSizeMin = min
	}

	// 如果从命令响应中没有获取到延迟信息，使用我们测量的
	if metrics.MaxLatency == 0 {
		metrics.MaxLatency = c.maxLatency
	}
	if metrics.MinLatency == 0 {
		metrics.MinLatency = c.minLatency
	}
	if metrics.AvgLatency == 0 && len(c.latencyHistory) > 0 {
		var sum float64
		for _, latency := range c.latencyHistory {
			sum += latency
		}
		metrics.AvgLatency = sum / float64(len(c.latencyHistory))
	}
}

// GetMetricValue 根据字段路径获取指标值
func (c *ZookeeperCollector) GetMetricValue(metrics *ZookeeperMetrics, fieldPath string) interface{} {
	if metrics == nil {
		return nil
	}

	switch fieldPath {
	case "Response.Time":
		return metrics.ResponseTime
	case "Response.LastSize":
		return metrics.ResponseSizeLast
	case "Response.MaxSize":
		return metrics.ResponseSizeMax
	case "Clients.Connected":
		return metrics.ClientConnected
	case "Cache.Enabled":
		return metrics.CacheEnabled
	case "Response.MinSize":
		return metrics.ResponseSizeMin
	case "Response.AvgSize":
		return metrics.ResponseSizeAvg
	case "Latency.Avg":
		return metrics.AvgLatency
	case "Latency.Max":
		return metrics.MaxLatency
	case "Latency.Min":
		return metrics.MinLatency
	case "ZNode.Count":
		return metrics.ZnodeCount
	case "Data.Size":
		return metrics.DataSize
	case "Server.State":
		return metrics.ServerState
	case "Version":
		return metrics.Version
	case "Packets.Sent":
		return metrics.PacketsSent
	case "Packets.Received":
		return metrics.PacketsReceived
	case "Requests.Outstanding":
		return metrics.OutstandingRequests
	default:
		logger.Warnf("未知的Zookeeper指标字段路径: %s", fieldPath)
		return nil
	}
}

// Close 关闭采集器
func (c *ZookeeperCollector) Close() error {
	// Zookeeper采集器没有需要关闭的资源
	return nil
}